io-xpm.c (xpm_extract_color): Rewritten to handle
authorMatthias Clasen <matthiasc@src.gnome.org>
Fri, 21 Sep 2001 21:39:42 +0000 (21:39 +0000)
committerMatthias Clasen <matthiasc@src.gnome.org>
Fri, 21 Sep 2001 21:39:42 +0000 (21:39 +0000)
xpm colormap entries more thoroughly. (#59939)

gdk-pixbuf/ChangeLog
gdk-pixbuf/io-xpm.c

index 280e9214e0965c7a1fe35150474020f66ebb8b9c..492549aeabe54fce2fe833723bb5418aefd87975 100644 (file)
@@ -1,3 +1,8 @@
+2001-09-21  Matthias Clasen  <matthiasc@poet.de>
+
+       * io-xpm.c (xpm_extract_color): Rewritten to handle
+       xpm colormap entries more thoroughly. (#59939)
+
 2001-09-21  Hans Breuer  <hans@breuer.org>
 
        * gdk-pixbuf.def : updated externals
index 9784b68d01e2dcf1dced79963a3e456f1517ec35..2505ddba1748853f7f4fab1af26b3c6edeb0f957 100644 (file)
@@ -943,14 +943,14 @@ parse_color (const char *spec,
                char fmt[16];
                int i, red, green, blue;
 
-               if ((i = strlen(spec+1))%3) {
+               if ((i = strlen (spec + 1)) % 3) {
                        return FALSE;
                }
                i /= 3;
 
                g_snprintf (fmt, 16, "%%%dx%%%dx%%%dx", i, i, i);
 
-               if (sscanf(spec+1, fmt, &red, &green, &blue) != 3) {
+               if (sscanf (spec + 1, fmt, &red, &green, &blue) != 3) {
                        return FALSE;
                }
                if (i == 4) {
@@ -1092,74 +1092,78 @@ xpm_skip_string (const gchar *buffer)
        return &buffer[index];
 }
 
-/* Xlib crashed once at a color name lengths around 125 */
-#define MAX_COLOR_LEN 120
-
 static gchar *
 xpm_extract_color (const gchar *buffer)
 {
-       gint counter, numnames;
-       const gchar *ptr = NULL;
-        gchar ch, temp[128];
-       gchar color[MAX_COLOR_LEN], *retcol;
-       gint space;
-
-       counter = 0;
-       while (ptr == NULL) {
-               if ((buffer[counter] == 'c') || (buffer[counter] == 'g')) {
-                       ch = buffer[counter + 1];
-                       if (ch == 0x20 || ch == 0x09)
-                               ptr = &buffer[counter + 1];
-               } else if (buffer[counter] == 0)
-                       return NULL;
-
-               counter++;
-       }
-       ptr = xpm_skip_whitespaces (ptr);
-
-       if (ptr[0] == 0)
-               return NULL;
-       else if (ptr[0] == '#') {
-               counter = 1;
-               while (ptr[counter] != 0 &&
-                      ((ptr[counter] >= '0' && ptr[counter] <= '9') ||
-                       (ptr[counter] >= 'a' && ptr[counter] <= 'f') ||
-                       (ptr[counter] >= 'A' && ptr[counter] <= 'F')))
-                       counter++;
-               retcol = g_new (gchar, counter + 1);
-               strncpy (retcol, ptr, counter);
-
-               retcol[counter] = 0;
-
-               return retcol;
-       }
-       color[0] = 0;
-       numnames = 0;
-
-       space = MAX_COLOR_LEN - 1;
-       while (space > 0) {
-               sscanf (ptr, "%127s", temp);
-
-               if (((gint) ptr[0] == 0) ||
-                   (strcmp ("s", temp) == 0) || (strcmp ("m", temp) == 0) ||
-                   (strcmp ("g", temp) == 0) || (strcmp ("g4", temp) == 0))
-                       break;
+       gint new_key = 0;
+       gint key = 0;
+       gint current_key = 1;
+       gint space = 128;
+       gchar word[128], color[128], current_color[128];
+       gchar *r, *p;
+
+       p = &buffer[0];
+       word[0] = '\0';
+       color[0] = '\0';
+       current_color[0] = '\0';
+        while (1) {
+               /* skip whitespace */
+               for (; *p != '\0' && g_ascii_isspace (*p); p++) {
+               } 
+               /* copy word */
+               for (r = word; *p != '\0' && !g_ascii_isspace (*p) && r - word < sizeof (word) - 1; p++, r++) {
+                       *r = *p;
+               }
+               *r = '\0';
+               if (*word == '\0') {
+                       if (color[0] == '\0')  /* incomplete colormap entry */
+                               return NULL;                            
+                       else  /* end of entry, still store the last color */
+                               new_key = 1;
+               } 
+               else if (key > 0 && color[0] == '\0')  /* next word must be a color name part */
+                       new_key = 0;
                else {
-                       if (numnames > 0) {
-                               space -= 1;
+                       if (strcmp (word, "c") == 0)
+                               new_key = 5;
+                       else if (strcmp (word, "g") == 0)
+                               new_key = 4;
+                       else if (strcmp (word, "g4") == 0)
+                               new_key = 3;
+                       else if (strcmp (word, "m") == 0)
+                               new_key = 2;
+                       else if (strcmp (word, "s") == 0)
+                               new_key = 1;
+                       else 
+                               new_key = 0;
+               }
+               if (new_key == 0) {  /* word is a color name part */
+                       if (key == 0)  /* key expected */
+                               return NULL;
+                       /* accumulate color name */
+                       if (color[0] != '\0') {
                                strcat (color, " ");
+                               space--;
                        }
-
-                       strncat (color, temp, space);
-                       space -= MIN (space, strlen (temp));
-                       ptr = xpm_skip_string (ptr);
-                       ptr = xpm_skip_whitespaces (ptr);
-                       numnames++;
+                       strncat (color, word, space);
+                       space -= MIN (space, strlen (word));
                }
+               else {  /* word is a key */
+                       if (key > current_key) {
+                               current_key = key;
+                               strcpy (current_color, color);
+                       }
+                       space = 128;
+                       color[0] = '\0';
+                       key = new_key;
+                       if (*p == '\0') break;
+               }
+               
        }
-
-       retcol = g_strdup (color);
-       return retcol;
+       if (current_key > 1)
+               return g_strdup (current_color);
+       else
+               return NULL; 
 }
 
 /* (almost) direct copy from gdkpixmap.c... loads an XPM from a file */